home *** CD-ROM | disk | FTP | other *** search
/ SGI Developer Toolbox 6.1 / SGI Developer Toolbox 6.1 - Disc 4.iso / public / tarmail / atob.c next >
C/C++ Source or Header  |  1994-08-01  |  3KB  |  138 lines

  1. /* atob: version 4.0
  2.  * stream filter to change printable ascii from "btoa" back into 8 bit bytes
  3.  * if bad chars, or Csums do not match: exit(1) [and NO output]
  4.  *
  5.  *  Paul Rutter        Joe Orost
  6.  *  philabs!per        petsd!joe
  7.  *
  8.  *  900308 rpw3        Modified for slightly more user-friendly usage message
  9.  */
  10.  
  11. #include <stdio.h>
  12.  
  13. #define reg register
  14.  
  15. #define streq(s0, s1)  strcmp(s0, s1) == 0
  16.  
  17. #define times85(x)    ((((((x<<2)+x)<<2)+x)<<2)+x)
  18.  
  19. long int Ceor = 0;
  20. long int Csum = 0;
  21. long int Crot = 0;
  22. long int word = 0;
  23. long int bcount = 0;
  24.  
  25. fatal() {
  26.   fprintf(stderr, "bad format or Csum to atob\n");
  27.   exit(1);
  28. }
  29.  
  30. #define DE(c) ((c) - '!')
  31.  
  32. decode(c) 
  33.   reg c;
  34. {
  35.   if (c == 'z') {
  36.     if (bcount != 0) {
  37.       fatal();
  38.     } else {
  39.       byteout(0);
  40.       byteout(0);
  41.       byteout(0);
  42.       byteout(0);
  43.     }
  44.   } else if ((c >= '!') && (c < ('!' + 85))) {
  45.     if (bcount == 0) {
  46.       word = DE(c);
  47.       ++bcount;
  48.     } else if (bcount < 4) {
  49.       word = times85(word);
  50.       word += DE(c);
  51.       ++bcount;
  52.     } else {
  53.       word = times85(word) + DE(c);
  54.       byteout((int)((word >> 24) & 255));
  55.       byteout((int)((word >> 16) & 255));
  56.       byteout((int)((word >> 8) & 255));
  57.       byteout((int)(word & 255));
  58.       word = 0;
  59.       bcount = 0;
  60.     }
  61.   } else {
  62.     fatal();
  63.   }
  64. }
  65.  
  66. FILE *tmp_file;
  67.  
  68. byteout(c) 
  69.   reg c;
  70. {
  71.   Ceor ^= c;
  72.   Csum += c;
  73.   Csum += 1;
  74.   if ((Crot & 0x80000000)) {
  75.     Crot <<= 1;
  76.     Crot += 1;
  77.   } else {
  78.     Crot <<= 1;
  79.   }
  80.   Crot += c;
  81.   putc(c, tmp_file);
  82. }
  83.  
  84. main(argc, argv) 
  85.   char **argv;
  86. {
  87.   reg c;
  88.   reg long int i;
  89.   char tmp_name[100];
  90.   char buf[100];
  91.   long int n1, n2, oeor, osum, orot;
  92.  
  93.   if (argc != 1) {
  94.     fprintf(stderr,"%s: no args allowed, please use pipes or re-direction\n", argv[0]);
  95.     exit(2);
  96.   }
  97.   sprintf(tmp_name, "/usr/tmp/atob.%x", getpid());
  98.   tmp_file = fopen(tmp_name, "w+");
  99.   if (tmp_file == NULL) {
  100.     fatal();
  101.   }
  102.   unlink(tmp_name);    /* Make file disappear */
  103.   /*search for header line*/
  104.   for (;;) {
  105.     if (fgets(buf, sizeof buf, stdin) == NULL) {
  106.       fatal();
  107.     }
  108.     if (streq(buf, "xbtoa Begin\n")) {
  109.       break;
  110.     }
  111.   }
  112.  
  113.   while ((c = getchar()) != EOF) {
  114.     if (c == '\n') {
  115.       continue;
  116.     } else if (c == 'x') {
  117.       break;
  118.     } else {
  119.       decode(c);
  120.     }
  121.   }
  122.   if(scanf("btoa End N %ld %lx E %lx S %lx R %lx\n",
  123.          &n1, &n2, &oeor, &osum, &orot) != 5) {
  124.     fatal();
  125.   }
  126.   if ((n1 != n2) || (oeor != Ceor) || (osum != Csum) || (orot != Crot)) {
  127.     fatal();
  128.   } else {
  129.     /*copy OK tmp file to stdout*/;
  130.     fseek(tmp_file, 0L, 0);
  131.     for (i = n1; --i >= 0;) {
  132.       putchar(getc(tmp_file));
  133.     }
  134.   }
  135.   exit(0);
  136. }
  137.  
  138.